﻿function jString(str) {
    if (null == str ) {
        throw new Error("jObject can not initialize with null value.");
    }
    else {
        this.o = str.toString();
        this.length = this.o.length;
    }
}

//***************** Start static methods of jString *******************
jString.create = function (str) {
    return new jString(str);
};

jString.format = function () {
    if (arguments.length == 0) return null;

    var str = arguments[0];
    var args = arguments;
    var res = str.replace(/\{(\d+)\}/g, function ($0, $1) {
        return args[parseInt($1) + 1];
    });
    return res;
}

jString.isNullOrEmpty = function (str) {
    if (null == str) return true;
    if ("" == str) return true;
    return false;
}

jString.isNullOrWhiteSpace = function (str) {
    if (null == str) return true;
    if ("" == str.trim()) return true;
    return false;
}
//***************** End static methods of jString *******************

//***************** Start prototype of jString *******************
jString.prototype = {

    charAt$: function (index) {
        //if out of scope return ''
        return this.o.charAt(index)
    },

    charAt: function (index) {
        //if out of scope return ''
        return jString.create(this.charAt$(index));
    },

    charCodeAt: function (index) {
        //If there is no character at the specified index, NaN is returned.
        return this.o.charCodeAt(index);
    },
    concat$: function () {
        return this.o.concat.apply(this.o, arguments);
    },
    concat: function () {
        return jString.create(this.concat$.apply(this, arguments));
    },
    indexOf: function (subString, startIndex) {
        return this.o.indexOf(subString, startIndex);
    },
    lastIndexOf: function (subString, startIndex) {
        return this.o.lastIndexOf(subString, startIndex);
    },
    localeCompare: function (stringExp) {
        return this.o.localeCompare(stringExp)
    },
    match: function (rgExp) {
        return this.o.match(rgExp)
    },
    replace$: function (rgExp, replaceText) {
        return this.o.replace(rgExp, replaceText)
    },
    replace: function (rgExp, replaceText) {
        var s = this.replace$(rgExp, replaceText);
        return (null == s) ? null : new jString(s);
    },

    search: function (rgExp) {
        return this.o.search(rgExp)
    },

    slice: function (start, end) {
        return this.o.slice(start, end)
    },

    split: function (separator, limit) {
        return this.o.split(separator, limit)
    },
    substr$: function (start, length) {
        return this.o.substr(start, length)
    },
    substr: function (start, length) {
        var s = this.substr$(start, length);
        return (null == s) ? null : new jString(s);
    },
    substring: function (start, end) {
        return this.o.substring(start, end)
    },
    toLocaleLowerCase: function () {
        return this.o.toLocaleLowerCase()
    },
    toLocaleUpperCase: function () {
        return this.o.toLocaleUpperCase()
    },
    toUpperCase: function () {
        return this.o.toUpperCase()
    },
    toLowerCase: function () {
        return this.o.toLowerCase()
    },
    trim: function () {
        return this.o.trim()
    },
    toString: function () {
        return this.o.toString()
    },
    valueOf: function () {
        return this.o.valueOf()
    },


    //***************** Start String Extension for jString *******************
    getType: function () {
        return "jString";
    },
    index: function (index) {
        //if out of scope return ''
        return this.o.charAt(index)
    },

    ascii: function (index) {
        //If there is no character at the specified index, NaN is returned.
        index = index || 0;
        return this.o.charCodeAt(index);
    },
    replaceAll: function (str, replaceText, ignoreCase) {
        ignoreCase = ignoreCase || false;
        if (ignoreCase) {
            return this.o.replace(new RegExp(str, "gmi"), replaceText);
        }
        else {
            return this.o.replace(new RegExp(str, "gm"), replaceText);
        }
    },
    toUpper: function () {
        return this.o.toUpperCase()
    },
    toLower: function () {
        return this.o.toLowerCase()
    },
    left$: function (len) {
        if (len <= 0) {
            return "";
        }
        else if (len > this.length) {
            len = this.length;
        }
        return this.o.substr(0, len);
    },
    left: function (len) {
        return jString.create(this.left$(len));
    },

    right$: function (len) {
        if (len <= 0) {
            return "";
        }
        else if (len > this.length) {
            len = this.length;
        }
        return this.o.substr(this.length - len, len);
    },
    right: function (len) {
        return jString.create(this.right$(len));
    },
    startsWith: function (str, ignoreCase) {
        ignoreCase = ignoreCase || false;
        var s = this.left$(str.length);
        return ignoreCase? (str.toLowerCase()==s.toLowerCase()): (str==s);
    },
    endsWith: function (str, ignoreCase) {
        ignoreCase = ignoreCase || false;
        var s = this.right$(str.length);
        return ignoreCase ? (str.toLowerCase() == s.toLowerCase()) : (str == s);
    },
    format: function () {
        //var args = arguments;
        //var res = this.o.replace(/\{(\d+)\}/g, function ($0, $1) { return args[parseInt($1)]; });
        var args = [this.o];
        for (var i = 0; i < arguments.length; i++) args.push(arguments[i]);
        res = jString.format.apply(this, args);
        return res;
    },

    insert: function (pos, str) {
        var len = this.o.length
        if (pos < 0) pos += len;
        if (pos > len - 1) pos = len - 1;
        var str = this.left(pos) + str + this.right(len - pos);
    },

    padLeft: function (len, str) { },

    padRight: function (len, str) { },

    remove: function (pos, len) { },

    trimLeft: function (str) { },

    trimRight: function (str) { }

    //***************** End String Extension for jString ******************

};

//***************** End prototype of jString *******************
